package test.serverframe.armc.server.manager.service.exec.dag;

import java.util.ArrayList;

/**
 * DAG节点
 */
public abstract class DagNode {

	// 节点所属的图，由DAG自动维护
	private Dag dag;
	// 节点id
	private String id;
	// 节点状态，由DAG自动维护
	private DagNodeState state = DagNodeState.Waiting;
	// 父节点列表，由DAG自动维护
	private ArrayList<DagNode> parents = new ArrayList<>();
	// 子节点列表，由DAG自动维护
	private ArrayList<DagNode> children = new ArrayList<>();
	
	/**
	 * 获取节点Id
	 * 
	 * @return
	 */
	public String getId() {
		return id;
	}

	/**
	 * 使节点死亡 ： 即表示该节点已经遍历，处理完成 节点状态规则： 1、状态必须遵循 Waiting -> Living -> Dead
	 * 顺序，不可逆,也不可以跳 2、当父节点全部 Dead 之后，本节点才能 Dead 节点状态变化 1、节点初始化时，状态为 Waiting
	 * 2、当节点的父节点全部 Dead 后，节点由 DAG 自动更改为 Living 状态 3、节点处理完成后，由外部调用此函数，让本节点 Dead
	 * 4、本节点 Dead 后，通知 DAG ，由 DAG 检查本节点的子节点，判断是否可以让子节点进入 Living 状态
	 */
	public Boolean putToDeath() {
		if (state == DagNodeState.Living) {
			state = DagNodeState.Dead;
			if (dag != null) {
				dag.handle_NodeIsDead(this);
			}
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 增加父节点，已经具备防重复，防Null功能
	 * 
	 * @param node
	 */
	protected void addParent(DagNode node) {
		if (node != null && !parents.contains(node)) {
			parents.add(node);
		}
	}

	/**
	 * 增加子节点，已经具备防重复，防Null功能
	 * 
	 * @param node
	 */
	protected void addChild(DagNode node) {
		if (node != null && !children.contains(node)) {
			children.add(node);
		}
	}

	/**
	 * 判断节点是否可以激活 判断规则： 1、（ 如果没有父节点，或者父节点全部为 Dead ） 而且 （ 本节点处于 Waiting ），本节点可以激活
	 * 2、其他情况，本节点都不能被激活
	 * 
	 * @return
	 */
	public boolean canActivate() {
		if (state == DagNodeState.Waiting) {
			if (parents != null) {
				for (DagNode node : parents) {
					if (node.state == DagNodeState.Living || node.state == DagNodeState.Waiting) {
						return false;
					}
				}
			}
			return true;
		} else {
			return false;
		}
	}

	public Dag getDag() {
		return dag;
	}

	public void setDag(Dag dag) {
		this.dag = dag;
	}

	public DagNodeState getState() {
		return state;
	}

	public void setState(DagNodeState state) {
		this.state = state;
	}

	public ArrayList<DagNode> getParents() {
		return parents;
	}

	public void setParents(ArrayList<DagNode> parents) {
		this.parents = parents;
	}

	public ArrayList<DagNode> getChildren() {
		return children;
	}

	public void setChildren(ArrayList<DagNode> children) {
		this.children = children;
	}

	public void setId(String id) {
		this.id = id;
	}

    public DagNode() {

	}
}
